
#include "init.h"
#include "Utils.h"
#include <queue>
#define DUM_BOT 0
//================================//
//	---		for User	 ---
//--------------------------------//
int attackPosX = 0;
int attackPosY = 0;

int myBoard[100];
int opponentBoard[100];

bool foundPatrol = false;

void AI_Init(Battleship* _this) 
{
	std::cout<<"\nINIT YOUR BOT HERE!!!"<<std::endl;
	srand (time(NULL));
};

void AI_ChooseFirstPlay(Battleship* _this)
{
	int choose_first_play_arr[3];

	for(int i = 0; i<3;i++)
	{
		choose_first_play_arr[i] = rand()%3;
	}

	_this->SetLottery(choose_first_play_arr);
}

void AI_EndSet(Battleship* _this)
{
	std::cout<<"*** END SET ***"<<std::endl;
	Utils::GetInstance()->EndSet();
	std::cout<<"Win:Lose:Turn " << _this->GetMyWin() <<":"<< _this->GetOpponentWin() <<":"<<_this->GetCurrentTurnNumber() / 2<< std::endl;
}

void AI_SetBoard(Battleship* _this)
{
	int cSet = _this->GetCurrentSet();
	std::cout<<"Set "<<cSet<<" start!"<<std::endl;
	Utils::GetInstance()->Initialize();

	BoardType map;
	Utils::GetInstance()->SetBoard(map);
	//BoardType map = {{2,3,8,1},{3,7,6,0},{3,8,1,1},{4,2,6,0},{5,0,0,0}};
	_this->SetMyBoard(map);


	//--- reset AI attack Pos ---
	attackPosX = -1;
	attackPosY = -1;
	foundPatrol = false;
};
#if DUM_BOT
void AI_Update(Battleship* _this)
{
	_this->SetAttackPos(5, 5);
}
#else
void AI_Update(Battleship* _this)
{
	// Get my current board  status
	_this->GetMyBoard(myBoard);
     Ship::TypeOfShip type;
	_this->GetOpponentBoard(opponentBoard);
    // Get the board status at position X,Y 
    // Note: it will return status of previous turn
    if(attackPosX >= 0 && attackPosY >= 0)
	{
		int k = _this->GetBoardStatusAt(opponentBoard, attackPosX, attackPosY);
		Utils::GetInstance()->Swap(attackPosX,attackPosY);
		switch(k)
		{
			case MISS:
				std::cout<<"Attack MISS at "<<attackPosX<<";"<<attackPosY<<std::endl;
				Utils::GetInstance()->ProcessPos(Point(attackPosX,attackPosY),false);
				break;
			case EMPTY:
				std::cout<<"EMPTY at "<<attackPosX<<";"<<attackPosY<<std::endl;
				break;
			case HIT:
				std::cout<<"Attack HIT at "<<attackPosX<<";"<<attackPosY<<std::endl;
				Utils::GetInstance()->ProcessPos(Point(attackPosX,attackPosY),true);
				break;
			case DISTROYER:
				type = Ship::DESTROYER;
				Utils::GetInstance()->ProcessPos(Point(attackPosX,attackPosY),true);
				Utils::GetInstance()->FoundShip(Point(attackPosX,attackPosY),type);
				break;
			case PATROL:
				if (foundPatrol)
				{
					type = Ship::PATROL;
				}
				else
				{
					type = Ship::SUBMARINE;
					foundPatrol = true;
				}
				Utils::GetInstance()->ProcessPos(Point(attackPosX,attackPosY),true);
				Utils::GetInstance()->FoundShip(Point(attackPosX,attackPosY),type);
				break;
			case BATTLESHIP:
				type = Ship::BATTLE;
				Utils::GetInstance()->ProcessPos(Point(attackPosX,attackPosY),true);
				Utils::GetInstance()->FoundShip(Point(attackPosX,attackPosY),type);
				break;
			case AIRCRAFT_CARRIER:
				type = Ship::AIRCRAFT;
				Utils::GetInstance()->ProcessPos(Point(attackPosX,attackPosY),true);
				Utils::GetInstance()->FoundShip(Point(attackPosX,attackPosY),type);
				break;
			default:
				std::cout<<"!!!ERROR!!!"<<std::endl;
				break;
        }
	}
	//_this->GetOpponentBoard(opponentBoard);
	Point p = Utils::GetInstance()->GuessPos();
	// Sent attack position
	std::cout<<"\nAttack pos: "<<p.first<<";"<<p.second<<std::endl;
	attackPosX = p.first;
	attackPosY = p.second;
	Utils::GetInstance()->Swap(attackPosX,attackPosY);
	_this->SetAttackPos(attackPosX, attackPosY);

	//std::cout << "AI_Update Done" << std::endl;
}
#endif
///////////////////////////////////////////////////////
////					DON'T TOUCH MAIN
///////////////////////////////////////////////////////
int main(int argc, char* argv[]) {
	srand ( time(NULL) );
	AppClientHandlerPtr temp(new AppClientHandler());
	s_con_handler = temp;
	
	//AI process
	Get_BOT_Name(argc,argv);

	Battleship::Init = &AI_Init;
	Battleship::ChooseFirstPlay = &AI_ChooseFirstPlay;
	Battleship::SetBoard = &AI_SetBoard;
	Battleship::Update = &AI_Update;
	Battleship::EndSet = &AI_EndSet;

	p_Battleship = new Battleship(bot_table_x, bot_table_y, bot_name, bot_avatar);

	boost::thread thr_cGame(boost::bind(&Battleship::Run,p_Battleship,s_con_handler));
		//Server process
		Connectiont();
		//End server process
	thr_cGame.join();

	delete p_Battleship;
	//End AI process	
    return 0;
}




